--[[
	自建桌子，里面就是最基本的打牌逻辑
]]
local filename = "table.lua"

local skynet = require "skynet"
local cluster = require "skynet.cluster"

local filelog = require "filelog"
local routerbase = require "routerbase"
require "yydbenum"

local json = require "cjson"
json.encode_sparse_array(true, 1, 1)

--
--构建一个桌子对象
--
local Table = routerbase:new({
	LOGICPOOL = {},
	table_data = {
        table_type = 0,	            --桌子类型：1：金币场
		uuid = "",                  --唯一id
        tradeid = 0,                --节点唯一id
		index = 0,  	            --就是 table_index
        code = "",                  --桌号
		state = 0,	                --状态
		sitdown_player_num = 0,     --坐下的玩家数

        table_service = nil,        --桌子服务

        waits = {},                 --旁观队列 （等待列表）
        seats = {},                 --座位信息

		conf = nil,                 --桌子配置（来自客户端）
		gamelogic = nil,            --游戏逻辑对象
		timer_id = -1,              --通用计时器
		isdeleting = false,           --是否被标示为可删除
		cur_watch_playernum = 0,    --当前旁观人数
        special_seats = {},

		--添加桌子的变量
		delete_table_timer_id = -1,     --删除倒计时
        check_robot_bet_timer_id = -1,  
		curr_to_num = 0,                --当前已经打了的局数
        today_already_times = 0,        --今天已经进行游戏的场数

		one_start_time = 0,             --单局开局时间
        one_end_time = 0,               --单局结束时间
        start_time = 0,                 --游戏开始时间
		end_time = 0,                   --游戏结束时间

        do_bet_timeout = 20,            --玩家下注操作的超时时间,单位s 
        countdown_time = 1,             --一局游戏开始的倒计时，单位s 
        spin_countdown_time = 1.5,      --转动倒计时

		banker_seat_index = 0,      --当前庄家位置		
		game_records = nil,         --游戏战绩记录

		is_had_start = false,       --是否已经开局
        is_onegameend = false,       --是否一局结束

        agencylevel = 0,            --代理等级，0表示非代理创建桌
        is_ingame = false,          --是否游戏中
        notice_betlist_timer = -1,  --通知下注列表定时器

        cur_bet_player_num = 0,     --当前下注玩家数
        cur_total_bet_num = 0,      --当前总下注值
        cur_total_bet_cnt = 0,      --当前总下注次数
        cur_total_bet_list = {},    --当前总下注列表

        up_banker_list = {},        --等待上庄列表
        action_timeout_time = 0,    --当前操作超时时的时间
        cur_jackpot_money = 0,      --当前奖池金额
        open_jackpot_countdown = 0, --开奖倒计时，开过一次后倒计时将会重置
        cur_jackpot_id = 0,         --奖池id
        open_jackpot_timestamp = 0, --开奖时的时间
        open_award_time = 0,
        each_total_bet_cnt_list = {},--每一个下注项不同底注的下注次数
        each_inc_bet_cnt_list   = {}, --每一个下注项不同底注的下注次数的变化列表
        
        all_random_codes_pool   = {},     ----开局按照系统上限金额生成一堆随机码  
        all_beted_players_codes = {},   ----所有下过注的玩家的随机码
        rids_with_random_codes  = {},    ----随机码和rid对应关系，方便快速查找
        all_beted_robot_codes   = {},
        open_award_random_codes_pool = {},   ----开奖一级池中所有的随机码(在下注时，会把下注得到的随机码放入这个池子，
                                        ----如果没放入这个池子，那就不可能中奖，防止撸羊毛的玩家)
        --[[
            [1] = {},   ---一级码池, ai 购买的码特别标识且在一级码池
            [2] = {},   ---二级码池, 低于10元下注(可调控)
        --]]

        open_award_result = {},         ----记录当局开奖结果
        --[[
            {
                open_award_code = "",   ---中奖code
                open_award_rid = 0,
                open_award_rolename = "", ---中奖玩家名字
                open_award_num  = 0,      ---实际获得的金钱
            }
        --]]
        player_bet_rank_data = {},      ---下注排行榜
        --[[
            [1] = {
                rid = rid,
                bet_num = bet_num,
            }
        --]]
        ----历史记录
        history_record_lists = {},
	},
})


--
-- 初始化数据
--
-- 注意这里的顺序要先 add_logic ,然后再 add_func
-- 因为 func里的init 有会使用 logic 里的定义，所以要先add_loginc
--
function Table:init()
	-- 放到LOGICPOOL{} 里面执行了
	self:add_logic("tablelogic", "tablemsg/tablelogic")  -- 桌子逻辑
	self:add_logic("seatlogic", "tablemsg/seatlogic")    -- 座位逻辑
    self:add_logic("tablerobothelper", "tablemsg/tablerobothelper")  -- 机器人逻辑	
	self:add_logic("gamelogic", "tablemsg/gamelogic")    -- 游戏逻辑
    

	-- 放到CMD{} 里面执行了
	self:add_func("tablemsg/tablecmd")
	self:add_func("tablemsg/tablerequest")
	self:add_func("tablemsg/tabletimer")
end

--
--添加逻辑处理模块
--
function Table:add_logic(name, logicfile)
	self.LOGICPOOL[name] = require(logicfile)
    if self.LOGICPOOL[name] then
	    if self.LOGICPOOL[name].init and type(self.LOGICPOOL[name].init) == "function" then
		    self.LOGICPOOL[name].init(self)
	    end
    else
        filelog.sys_error("add logic failed!",name,logicfile)
    end
end

--
--通过logic_name，获得逻辑对象
--
function Table:get_logicbyname(logic_name)
	return self.LOGICPOOL[logic_name]
end

--
--向列表中玩家发通知消息
--is_new_format 是否新格式
--
function Table:send_notice_to_players(rids, msgname, message, retcode, retstr, is_new_format)
    local status = true

    if is_new_format then
        local tmp = { msgname = msgname, msgbody = json.encode(message)}
        status = skynet.pcall(cluster.send,"gatenode", ".router", "notify", rids, "yydb.".. "notifyN", tmp, retcode, retstr)
        ---status = skynet.pcall(cluster.send, "gatenode", ".mainnode", "cmd", "notify", rids, "yydb.".. "notifyN", tmp, retcode, retstr)
    else
	    status = skynet.pcall(cluster.send,"gatenode", ".router", "notify", rids, "yydb."..msgname, message, retcode, retstr)
        ---status = skynet.pcall(cluster.send,"gatenode", ".mainnode", "cmd", "notify", rids, "yydb."..msgname, message, retcode, retstr)
    end
    if not status then
        filelog.sys_error("notice player failed!")
    end
end

--
--  通知gate
--
function Table:notice_tableinfo_togatenode(msgname, rid, gamenode, table_index)
	local status = skynet.pcall(cluster.send,"gatenode", ".router", msgname, rid, gamenode, table_index)
    if not status then
        filelog.sys_error("send msg to gate error!")
    end
end

--
--  结束服务
--
function Table:exit_service()
	skynet.exit()
end

--
-- lua消息处理
--
function Table:process(command, ...)
	skynet.call(skynet.self(), "lua", command, ...)
end

skynet.start(function()
	Table:start()
end)